package com.bkgy.controller.tcmReport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.commom.model.Temp2;
import com.bkgy.controller.tPdiDataL3Tcm2280.entity.TPdiDataL3Tcm2280;
import com.bkgy.controller.tPdiDataL3Tcm2280.service.ITPdiDataL3Tcm2280Service;
import com.bkgy.controller.tcmReport.entity.RepTcmOutputInf;
import com.bkgy.controller.tcmReport.entity.TbTcmEffOpenParams;
import com.bkgy.controller.tcmReport.entity.pdo.TcmOutputInfRes;
import com.bkgy.controller.tcmReport.entity.pdo.TcmRank;
import com.bkgy.controller.tcmReport.entity.pdo.TcmRankReTimes;
import com.bkgy.controller.tcmReport.mapper.IRepTcmOutputInfMapper;
import com.bkgy.controller.tcmReport.service.IRepTcmOutputInfService;
import com.bkgy.controller.tcmReport.service.ITbTcmEffOpenParamsService;
import com.bkgy.controller.tpdol3data.entity.OutputSec;
import com.bkgy.modular.tpdidata_cal1630.entity.TPdiDataMes2280;
import com.bkgy.modular.tpdidata_cal1630.service.ITPdiDataMesService;
import com.bkgy.sys.common.constant.CommonConstant;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
@RequiredArgsConstructor
public class RepTcmOutputInfServiceImpl extends ServiceImpl<IRepTcmOutputInfMapper, RepTcmOutputInf> implements IRepTcmOutputInfService {
    private final IRepTcmOutputInfMapper mapper;
    private final ITPdiDataMesService pdiMesService;
    private final ITPdiDataL3Tcm2280Service pdiTcm2280Service;
    private final ITbTcmEffOpenParamsService kaijuanLevelService;

    @Override
    public ResultData<TcmOutputInfRes> infOutput(String date) {
        LambdaQueryWrapper<RepTcmOutputInf> w = new LambdaQueryWrapper<>();
        w.eq(RepTcmOutputInf::getShijian, date);
        List<RepTcmOutputInf> list = list(w);
        List<TcmOutputInfRes> resList = new ArrayList<>();
        BigDecimal chonghanTotal = BigDecimal.ZERO;
        BigDecimal kaijuanTotal = BigDecimal.ZERO;
        BigDecimal hejiTotal = BigDecimal.ZERO;
        int jianqie = 0;
        for (RepTcmOutputInf r : list) {
            TcmOutputInfRes res = new TcmOutputInfRes();
            res.setCrew(CommonConstant.crewMap.get(r.getCrew()));
            res.setChonghanOutput(r.getChonghanOutput());
            res.setKaijuanOutput(r.getKaijuanOutput());
            res.setJianqieOutput(r.getJianqieOutput());
            res.setTotalOutput(r.getChonghanOutput().add(r.getKaijuanOutput()));
            resList.add(res);
            chonghanTotal = chonghanTotal.add(r.getChonghanOutput());
            kaijuanTotal = kaijuanTotal.add(r.getKaijuanOutput());
            jianqie = jianqie + r.getJianqieOutput();
            hejiTotal = hejiTotal.add(res.getTotalOutput());
        }

        TcmOutputInfRes res = new TcmOutputInfRes();
        res.setCrew("合 计");
        res.setChonghanOutput(chonghanTotal);
        res.setKaijuanOutput(kaijuanTotal);
        res.setJianqieOutput(jianqie);
        res.setTotalOutput(hejiTotal);
        resList.add(res);
        return ResultData.ResultDataSuccess(resList, resList.size());
    }

    @Override
    public void buildInfOutputJob(Date d1) {
        String beginDate = DateUtil.getDateToString(d1, "yyyyMMdd");
        String endDate = DateUtil.getDateToString(DateUtil.getNextDayZero(d1), "yyyyMMdd");
        Map<String, RepTcmOutputInf> map = new HashMap<>();

        //构建重焊影响产量数据
        chonghanInf(beginDate, endDate, map);

        //构建开卷影响产量数据
        kaijuanInf(beginDate, endDate, map);

        //异常剪切次数
        List<Temp2> cutList = mapper.selectCrewCutCount(beginDate, endDate);
        for (Temp2 t : cutList) {
            String crew = t.getK();
            if (!map.containsKey(crew)) {
                RepTcmOutputInf rep = new RepTcmOutputInf();
                rep.setShijian(beginDate.substring(0, 8));
                rep.setCrew(crew);
                rep.setJianqieOutput(t.getV());
                map.put(crew, rep);
            } else {
                RepTcmOutputInf rep = map.get(crew);
                rep.setJianqieOutput(rep.getJianqieOutput() + t.getV());
            }
        }

        saveBatch(map.values());
    }

    /**
     * 开卷影响产量
     */
    private void kaijuanInf(String beginDate, String endDate, Map<String, RepTcmOutputInf> map) {
        //不同钢种分档的 装卷、开卷、穿卷、切头平均值
        Map<String, TbTcmEffOpenParams> kaijuanExcList = new HashMap<>();

        //查询班组、入轧卷号、分档
        List<TcmRank> list = mapper.selectRank(beginDate, endDate);
        //按班分组
        Map<String, List<TcmRank>> crewReMap = new HashMap<>();
        for (TcmRank t : list) {
            if (!crewReMap.containsKey(t.getCrew())) {
                List<TcmRank> l = new ArrayList<>();
                l.add(t);
                crewReMap.put(t.getCrew(), l);
            } else {
                crewReMap.get(t.getCrew()).add(t);
            }
        }

        //分班统计
        for (Map.Entry<String, List<TcmRank>> entry : crewReMap.entrySet()) {
            //分档统计
            Map<String, List<TcmRank>> rankMap = new HashMap<>();
            for (TcmRank t : entry.getValue()) {
                String key = t.getYpClass() + "_" + t.getExthkClass() + "_" + t.getExwidthClass() + "_" + t.getWeightUnit();
                if (!rankMap.containsKey(key)) {
                    List<TcmRank> l = new ArrayList<>();
                    l.add(t);
                    rankMap.put(key, l);
                } else {
                    rankMap.get(key).add(t);
                }
            }

            //影响总产量
            BigDecimal outputTotal = BigDecimal.ZERO;
            for (Map.Entry<String, List<TcmRank>> e : rankMap.entrySet()) {
                String[] arr = e.getKey().split("_");
                //分档标准时间
                LambdaQueryWrapper<TbTcmEffOpenParams> w = new LambdaQueryWrapper<>();
                w.eq(TbTcmEffOpenParams::getYpClass, arr[0]).eq(TbTcmEffOpenParams::getExthkClass, arr[1])
                        .eq(TbTcmEffOpenParams::getExwidthClass, arr[2]).eq(TbTcmEffOpenParams::getWeightUnit, arr[3]);
                TbTcmEffOpenParams one = kaijuanLevelService.getOne(w);
                int standLevel = 0;
                if (one != null) {
                    standLevel = one.getCarToExpandTime() + one.getExpandToStraightTime() + one.getStraightToCutterTime() + one.getCutterToWaitTime();
                } else {
                    //没有此档开卷标准
                    int carToExpandTime = 0;
                    int expandToStraightTime = 0;
                    int straightToCutterTime = 0;
                    int cutterToWaitTime = 0;
                    List<TcmRank> l = e.getValue();
                    for (TcmRank t : l) {
                        carToExpandTime += t.getCarToExpandTime();
                        expandToStraightTime += t.getExpandToStraightTime();
                        straightToCutterTime += t.getStraightToCutterTime();
                        cutterToWaitTime += t.getCutterToWaitTime();
                    }
                    TbTcmEffOpenParams p = new TbTcmEffOpenParams();
                    p.setYpClass(arr[0]);
                    p.setExthkClass(arr[1]);
                    p.setExwidthClass(arr[2]);
                    p.setWeightUnit(arr[3]);
                    p.setCarToExpandTime(carToExpandTime / l.size());
                    p.setExpandToStraightTime(expandToStraightTime / l.size());
                    p.setStraightToCutterTime(straightToCutterTime / l.size());
                    p.setCutterToWaitTime(cutterToWaitTime / l.size());
                    kaijuanExcList.put(e.getKey(), p);
                }
                //此分档总超过平均值时间
                int totalSec = 0;
                List<TcmRank> l = e.getValue();
                String prodStartTime = l.get(0).getProdStartTime();
                Date d = DateUtil.getStringToDate("yyyyMMddHHmmss", prodStartTime);
                for (TcmRank t : l) {
                    int currentSec = t.getCarToExpandTime() + t.getExpandToStraightTime() + t.getStraightToCutterTime() + t.getCutterToWaitTime();
                    if (currentSec > standLevel) {
                        totalSec += (currentSec - standLevel);
                    }
                }
                OutputSec outputSec = sumOutputSecInfo(d, totalSec);
                if (outputSec != null) {
                    outputTotal = outputTotal.add(outputSec.getTotalOutput());
                }
            }

            String crew = entry.getKey();
            if (!map.containsKey(crew)) {
                RepTcmOutputInf rep = new RepTcmOutputInf();
                rep.setShijian(beginDate.substring(0, 8));
                rep.setCrew(crew);
                rep.setKaijuanOutput(outputTotal);
                map.put(crew, rep);
            } else {
                RepTcmOutputInf rep = map.get(entry.getKey());
                rep.setKaijuanOutput(outputTotal);
            }
        }

        //出现新的分档保存
        if (kaijuanExcList.size() > 0) kaijuanLevelService.saveBatch(kaijuanExcList.values());
    }

    /**
     * 重焊影响产量
     */
    private void chonghanInf(String beginDate, String endDate, Map<String, RepTcmOutputInf> map) {
        //查询班组、分档、重焊次数、生产开始时间
        List<TcmRankReTimes> list = mapper.selectRankReWeldTimes(beginDate, endDate);
        //按班分组
        Map<String, List<TcmRankReTimes>> crewReMap = new HashMap<>();
        for (TcmRankReTimes t : list) {
            if (!crewReMap.containsKey(t.getCrew())) {
                List<TcmRankReTimes> l = new ArrayList<>();
                l.add(t);
                crewReMap.put(t.getCrew(), l);
            } else {
                crewReMap.get(t.getCrew()).add(t);
            }
        }

        //按班组分别统计
        for (Map.Entry<String, List<TcmRankReTimes>> entry : crewReMap.entrySet()) {
            //分档统计
            Map<String, List<TcmRankReTimes>> rankMap = new HashMap<>();
            for (TcmRankReTimes t : entry.getValue()) {
                //跳过4个值有空的情况
                if (StringUtils.isEmpty(t.getYpClass()) || StringUtils.isEmpty(t.getExthkClass())
                        || StringUtils.isEmpty(t.getExwidthClass()) || StringUtils.isEmpty(t.getWeightUnit())) {
                    continue;
                }
                String key = t.getYpClass() + "_" + t.getExthkClass() + "_" + t.getExwidthClass() + "_" + t.getWeightUnit();
                if (!rankMap.containsKey(key)) {
                    List<TcmRankReTimes> l = new ArrayList<>();
                    l.add(t);
                    rankMap.put(key, l);
                } else {
                    rankMap.get(key).add(t);
                }
            }

            //影响总产量
            BigDecimal outputTotal = BigDecimal.ZERO;
            //重焊次数
            int reWeldTimeTotal = 0;
            for (Map.Entry<String, List<TcmRankReTimes>> e : rankMap.entrySet()) {
                int reWeldTime = 0;//分档总重焊次数
                List<TcmRankReTimes> rankList = e.getValue();
                String prodEndTime = rankList.get(0).getProdStartTime();
                Date d = DateUtil.getStringToDate("yyyyMMddHHmmss", prodEndTime);
                for (TcmRankReTimes t : rankList) {
                    reWeldTime += (t.getWeldTimes() - 1);
                }
                reWeldTimeTotal += reWeldTime;
                String[] arr = e.getKey().split("_");
                Integer sec = mapper.selectReWeld(arr[0], arr[1], arr[2], arr[3]);
                if (sec != null) {
                    OutputSec outputSec = sumOutputSecInfo(d, reWeldTime * sec);
                    outputTotal = outputTotal.add(outputSec.getTotalOutput());
                }
            }

            String crew = entry.getKey();
            if (!map.containsKey(crew)) {
                RepTcmOutputInf rep = new RepTcmOutputInf();
                rep.setShijian(beginDate.substring(0, 8));
                rep.setCrew(crew);
                rep.setChonghanCount(reWeldTimeTotal);
                rep.setChonghanOutput(outputTotal);
                map.put(crew, rep);
            } else {
                RepTcmOutputInf rep = map.get(entry.getKey());
                rep.setChonghanCount(reWeldTimeTotal);
                rep.setChonghanOutput(outputTotal);
            }
        }
    }

    private OutputSec sumOutputSecInfo(Date beginDeate, long totalSec) {
        if (totalSec == 0) return null;
        OutputSec sec = new OutputSec();

        LambdaQueryWrapper<TPdiDataMes2280> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(TPdiDataMes2280::getInnerInMatNo, TPdiDataMes2280::getOutputSe, TPdiDataMes2280::getToc);
        wrapper.ge(TPdiDataMes2280::getToc, beginDeate).orderByAsc(TPdiDataMes2280::getToc);
        List<TPdiDataMes2280> mesList = pdiMesService.list(wrapper);
        int sumSec = 0;
        List<String> entIdList = new ArrayList<>();
        for (int i = 0; i < mesList.size(); i++) {
            TPdiDataMes2280 me = mesList.get(i);
            if (sumSec + me.getOutputSe() > totalSec) {
                sumSec += me.getOutputSe();
                entIdList.add(me.getInnerInMatNo());
                break;
            } else {
                sumSec += me.getOutputSe();
            }
        }

        BigDecimal sumOutput = BigDecimal.ZERO;
        if (entIdList.size() > 0) {
            LambdaQueryWrapper<TPdiDataL3Tcm2280> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.select(TPdiDataL3Tcm2280::getEntid, TPdiDataL3Tcm2280::getInMatWt);
            wrapper2.in(TPdiDataL3Tcm2280::getEntid, entIdList);
            List<TPdiDataL3Tcm2280> pdiList = pdiTcm2280Service.list(wrapper2);
            for (TPdiDataL3Tcm2280 p : pdiList) {
                sumOutput = sumOutput.add(p.getInMatWt());
            }
        }

        //按比例修正产量
        sec.setTotalOutput(sumOutput.multiply(BigDecimal.valueOf(totalSec)).divide(BigDecimal.valueOf(sumSec), 2, RoundingMode.HALF_UP));
        return sec;
    }
}
